本篇請與上一篇一起服用。
頁面按鈕在啟用前,在右上角呈現黑白的狀態,在開發者設計的情景下才會啟用。對使用者來說,這樣可以減少干擾。對開發者來說,可以減少不必要的錯誤。
一言以蔽之,你的按鈕如果不是在任何頁面都有作用,請使用頁面按鈕,否則請使用瀏覽器按鈕。
按鈕的啟用方式需要工程師自己實作及設定,以下介紹兩種啟用頁面按鈕的方式。
首先來看以下這段設定檔以及事件腳本
設定檔:
{
"manifest_version" : 2,
"name" : "鐵人賽-Page-Action1",
"description" : "啟用方法一:只有在主機是:www.google.com.tw的網域底下啟用此頁面按鈕",
"version" : "2.0",
"page_action" : {
"default_title" : "啟用方法一",
"default_icon" : "icon.png",
"default_popup": "popup.html"
},
"background" : {
"scripts" : ["event.js"],
"persistent" : false
},
"permissions" : ["tabs"]
}
事件腳本
//指定比對的url:不允許片段表達式
//例如: *://*.google.com.tw/* 作為查詢字串不被接受因為host是一個片段表達式
var urlPattern = '*://www.google.com.tw/*';
//利用 tabs.query api 查找畫面上的所有tab
function queryTabsAndShowPageActions(queryObject) {
chrome.tabs.query(queryObject,
function(tabs) {
if (tabs && tabs.length > 0) {
for (var i = 0; i < tabs.length; i++) {
//在加載完畢的tab上,使用chrome.pageAction.show 啟用按鈕
if (tabs[i].status === "complete") chrome.pageAction.show(tabs[i].id);
}
}
}
);
}
//第一次的初始化
chrome.runtime.onInstalled.addListener(function() {
queryTabsAndShowPageActions({
"active": false,
"currentWindow": true,
"url": urlPattern
});
});
//每次tab有變動,檢查現在這個current tab是否在指定的 url pattern底下
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
queryTabsAndShowPageActions({
"active": true,
"currentWindow": true,
"url": urlPattern
});
});
上面這段腳本描述了兩段處理邏輯:
其一:處理已開啟的Tabs,使用query api來繞遍所有的已開的網址,並在載入完畢的tab中啟用頁面按鈕
//第一次的初始化
chrome.runtime.onInstalled.addListener(function() {
queryTabsAndShowPageActions({
"active": false,
"currentWindow": true,
"url": urlPattern
});
});
其二:處理新開啟的Tabs,查詢是否為指定網域,並啟用tab中的頁面按鈕。
//每次tab有變動,檢查現在這個current tab是否在指定的 url pattern底下
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
queryTabsAndShowPageActions({
"active": true,
"currentWindow": true,
"url": urlPattern
});
});
這樣就完成了一個,只有在*://www.google.com.tw/*
底下會啟用的頁面按鈕。
完整範例在:Github
所以說其實也是可以偷吃步在所有tab開啟頁面按鈕,不過這樣作並沒有太大的意義。
除了使用url,應該也能籍由內容腳本來偵測有無特定的DOM物件,然後通知事件腳本處理。不過如果只是這樣有更方便的方式,讓我們繼續往下看方法二。
chrome.tabs.query允許使用者用物件作為第一個參數查詢使用者目前開啟的所有書籤,在上面的程式碼中示範了在目前使用的視窗下,取得目前瀏覽的頁籤。回傳值會是一個tab物件,內含了網站url、title、等有用資訊。
使用tabs.query
來查詢頁籤,可以使用Matches Patterns來過瀘取得的頁籤,但有一個很重要的限制,tabs.query不允許你使用片段表達式。
例如:
錯誤:會回傳不合規則的網址表達式
chrome.tabs.query({
"active": false,
"currentWindow": true,
"url": `*://www.google.com.*/*`
},
function(tabs) {
});
糾正結果:使用陣列指定多國家的google網域
chrome.tabs.query({
"active": false,
"currentWindow": true,
"url": ['`*://www.google.com.tw/*','`*://www.google.com.hk/*'`]`
},
function(tabs) {
});
接下來我們來討論另一種啟用頁面按鈕的方式,使用申明式內容(DeclarativeContent API)來啟用頁面按鈕。
以下截錄自chrome.declarativeContent API的非官方中文文件:https://crxdoc-zh.appspot.com/extensions/declarativeContent
使用chrome.declarativeContent API根據網頁內容進行某些操作,而不需要讀取網頁內容的權限。
聲明式內容API允許您根據網頁的URL和它的內容匹配的CSS選擇器來顯示您的擴展程序的頁面按鈕,而不需要擁有主機權限或插入內容腳本。為了在用戶單擊您的頁面按鈕後能夠與網頁交互,請使用activeTab權限。
如果您需要更精確地控制什麼時候顯示您的頁面按鈕,或者需要在用戶單擊它之前更改它的外觀以匹配當前標籤頁,您還是需要繼續使用頁面按鈕API。
設定檔
{
"manifest_version" : 2,
"name" : "鐵人賽-Page-Action2",
"description" : "啟用方法二:只有在主機是:www.google.com.tw 的網域底下啟用此頁面按鈕",
"version" : "2.0",
"page_action" : {
"default_title" : "啟用方法二",
"default_icon" : "icon.png",
"default_popup": "popup.html"
},
"background" : {
"scripts" : ["event.js"],
"persistent" : false
},
//記得宣告declarativeContent權限
"permissions" : ["tabs","declarativeContent"]
}
以下程試碼展示了,當https://www.google.com/
上的頁面存在密碼字段時,為該頁面啟用頁面按鈕。注意:所有條件(conditions)跟動作(actions)都使用new建構式。
//事件腳本
var rule = {
//條件
conditions: [
new chrome.declarativeContent.PageStateMatcher({
//url的匹配指定
pageUrl: { hostContains: 'www.google.com.tw' },
//必需擁有此dom物件, 以css選擇器的行形式宣告
css: ["img"]
})
],
//動作:啟用頁面按鈕
actions: [new chrome.declarativeContent.ShowPageAction()]
};
規則的條件可以多個,以下為例:
var rule = {
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostContains: 'www.google.com'},
css: ["img"]
}),
new chrome.declarativeContent.PageStateMatcher({
css: ["video"]
})
],
actions: [ new chrome.declarativeContent.ShowPageAction() ]
};
然後最重要的一點,記得在瀏覽器重啟時,去註消或是重新註冊規則:
//刪除規則,並重新註冊
chrome.runtime.onInstalled.addListener(function(details) {
//移除所有舊規則
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
//註冊新規則
chrome.declarativeContent.onPageChanged.addRules([rule]);
});
});
img tag
的畫面,按鈕才會啟用。例如:https://www.google.com.tw/#q=haha
完整範例在:Github
資源: